package singlestat
import (
"fmt"
"strings"
"github.com/K-Phoen/grabana/errors"
"github.com/K-Phoen/grabana/links"
"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/influxdb"
"github.com/K-Phoen/grabana/target/prometheus"
"github.com/K-Phoen/grabana/target/stackdriver"
"github.com/K-Phoen/sdk"
)
type Option func (stat *SingleStat ) error
type StatType string
const (
Min StatType = "min"
Max StatType = "max"
Avg StatType = "avg"
Current StatType = "current"
Total StatType = "total"
First StatType = "first"
Delta StatType = "delta"
Diff StatType = "diff"
Range StatType = "range"
Name StatType = "name"
)
type ValueMap struct {
Value string
Text string
}
type RangeMap struct {
From string
To string
Text string
}
var valueToTextMapping = 1
var rangeToTextMapping = 2
type SingleStat struct {
Builder *sdk .Panel
}
func New (title string , options ...Option ) (*SingleStat , error ) {
panel := &SingleStat {Builder : sdk .NewSinglestat (title )}
valueToText := "value to text"
rangeToText := "range to text"
panel .Builder .IsNew = false
mappingType := uint (valueToTextMapping )
panel .Builder .SinglestatPanel .MappingType = &mappingType
panel .Builder .SinglestatPanel .MappingTypes = []*sdk .MapType {
{
Name : &valueToText ,
Value : &valueToTextMapping ,
},
{
Name : &rangeToText ,
Value : &rangeToTextMapping ,
},
}
panel .Builder .SinglestatPanel .SparkLine = sdk .SparkLine {}
for _ , opt := range append (defaults (), options ...) {
if err := opt (panel ); err != nil {
return nil , err
}
}
return panel , nil
}
func defaults() []Option {
return []Option {
Span (6 ),
ValueFontSize ("100%" ),
ValueType (Avg ),
Colors ([3 ]string {"#299c46" , "rgba(237, 129, 40, 0.89)" , "#d44a3a" }),
ValuesToText ([]ValueMap {
{
Value : "null" ,
Text : "N/A" ,
},
}),
SparkLineColor ("rgb(31, 120, 193)" ),
SparkLineFillColor ("rgba(31, 118, 189, 0.18)" ),
}
}
func Links (panelLinks ...links .Link ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Links = make ([]sdk .Link , 0 , len (panelLinks ))
for _ , link := range panelLinks {
singleStat .Builder .Links = append (singleStat .Builder .Links , link .Builder )
}
return nil
}
}
func DataSource (source string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Datasource = &sdk .DatasourceRef {LegacyName : source }
return nil
}
}
func WithPrometheusTarget (query string , options ...prometheus .Option ) Option {
target := prometheus .New (query , options ...)
return func (singleStat *SingleStat ) error {
singleStat .Builder .AddTarget (&sdk .Target {
RefID : target .Ref ,
Hide : target .Hidden ,
Expr : target .Expr ,
IntervalFactor : target .IntervalFactor ,
Interval : target .Interval ,
Step : target .Step ,
LegendFormat : target .LegendFormat ,
Instant : target .Instant ,
Format : target .Format ,
})
return nil
}
}
func WithGraphiteTarget (query string , options ...graphite .Option ) Option {
target := graphite .New (query , options ...)
return func (singleStat *SingleStat ) error {
singleStat .Builder .AddTarget (target .Builder )
return nil
}
}
func WithInfluxDBTarget (query string , options ...influxdb .Option ) Option {
target := influxdb .New (query , options ...)
return func (singleStat *SingleStat ) error {
singleStat .Builder .AddTarget (target .Builder )
return nil
}
}
func WithStackdriverTarget (target *stackdriver .Stackdriver ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .AddTarget (target .Builder )
return nil
}
}
func Span (span float32 ) Option {
return func (singleStat *SingleStat ) error {
if span < 1 || span > 12 {
return fmt .Errorf ("span must be between 1 and 12: %w" , errors .ErrInvalidArgument )
}
singleStat .Builder .Span = span
return nil
}
}
func Height (height string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Height = &height
return nil
}
}
func Description (content string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Description = &content
return nil
}
}
func Transparent () Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Transparent = true
return nil
}
}
func Unit (unit string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .Format = unit
return nil
}
}
func Decimals (count int ) Option {
return func (singleStat *SingleStat ) error {
if count < 0 {
return fmt .Errorf ("decimals must be greater than 0: %w" , errors .ErrInvalidArgument )
}
singleStat .Builder .SinglestatPanel .Decimals = count
return nil
}
}
func SparkLine () Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .Show = true
singleStat .Builder .SinglestatPanel .SparkLine .Full = false
return nil
}
}
func FullSparkLine () Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .Show = true
singleStat .Builder .SinglestatPanel .SparkLine .Full = true
return nil
}
}
func SparkLineColor (color string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .LineColor = &color
return nil
}
}
func SparkLineFillColor (color string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .FillColor = &color
return nil
}
}
func SparkLineYMin (value float64 ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .YMin = &value
return nil
}
}
func SparkLineYMax (value float64 ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .SparkLine .YMax = &value
return nil
}
}
func ValueType (valueType StatType ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .ValueName = string (valueType )
return nil
}
}
func ValueFontSize (size string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .ValueFontSize = size
return nil
}
}
func Prefix (prefix string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .Prefix = &prefix
return nil
}
}
func PrefixFontSize (size string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .PrefixFontSize = &size
return nil
}
}
func Postfix (postfix string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .Postfix = &postfix
return nil
}
}
func PostfixFontSize (size string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .PostfixFontSize = &size
return nil
}
}
func ColorValue () Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .ColorValue = true
return nil
}
}
func ColorBackground () Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .ColorBackground = true
return nil
}
}
func Thresholds (values [2 ]string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .Thresholds = strings .Join ([]string {values [0 ], values [1 ]}, "," )
return nil
}
}
func Colors (values [3 ]string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .SinglestatPanel .Colors = []string {values [0 ], values [1 ], values [2 ]}
return nil
}
}
func ValuesToText (mapping []ValueMap ) Option {
return func (singleStat *SingleStat ) error {
valueMap := make ([]sdk .ValueMap , 0 , len (mapping ))
for _ , entry := range mapping {
valueMap = append (valueMap , sdk .ValueMap {
Op : "=" ,
TextType : entry .Text ,
Value : entry .Value ,
})
}
mappingType := uint (valueToTextMapping )
singleStat .Builder .SinglestatPanel .MappingType = &mappingType
singleStat .Builder .SinglestatPanel .ValueMaps = valueMap
return nil
}
}
func RangesToText (mapping []RangeMap ) Option {
return func (singleStat *SingleStat ) error {
rangeMap := make ([]*sdk .RangeMap , 0 , len (mapping ))
for i := range mapping {
rangeMap = append (rangeMap , &sdk .RangeMap {
From : &mapping [i ].From ,
To : &mapping [i ].To ,
Text : &mapping [i ].Text ,
})
}
mappingType := uint (rangeToTextMapping )
singleStat .Builder .SinglestatPanel .MappingType = &mappingType
singleStat .Builder .SinglestatPanel .RangeMaps = rangeMap
return nil
}
}
func Repeat (repeat string ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .Repeat = &repeat
return nil
}
}
func RepeatDirection (direction sdk .RepeatDirection ) Option {
return func (singleStat *SingleStat ) error {
singleStat .Builder .RepeatDirection = &direction
return nil
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .